package com.ruoyi.flow.common.tools.mediaconverter.converter.converter;


import com.ruoyi.flow.common.tools.mediaconverter.converter.command.CommandInvoker;
import com.ruoyi.flow.common.tools.mediaconverter.converter.ffmpeg.FfmpegInvoker;
import com.ruoyi.flow.common.tools.mediaconverter.converter.ffmpeg.FfmpegLocator;
import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkState;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 音频转换工具，支持将silk V3格式、amr格式和aud格式的音频转换为MP3格式
 *
 * @author Administrator
 */
@Converter(srcFormat = "silk", destFormat = "mp3")
public class Silk2Mp3Converter extends IConverter {
	private static Logger LOGGER = LoggerFactory.getLogger(Silk2Mp3Converter.class);
	private static final String SILK_DECODER_LINUX = "./decoder";
	private static final String SILK_DECODER_WINDOWS = "D:\\silk2mp3\\silk_v3_decoder.exe";
	private static final String SILK_DECODER_DIR_LINUX = "/usr/local/silk-v3-decoder-master/silk";
	private static final String SILK_DECODER_DIR_WINDOWS = "D:\\silk2mp3";

	public Silk2Mp3Converter(String srcFilePath, String destFilePath) {
		super(srcFilePath, destFilePath);
	}

	@Override
	public FfmpegInvoker createInvoker(FfmpegLocator locator) {
		File pcmFile = convertToPcm(srcFilePath);
		if (pcmFile == null || !pcmFile.exists()) {
			LOGGER.error("PCM文件不存在，请重新转换", new IllegalArgumentException("PCM文件不存在，请重新转换"));
			return null;
		} else {
			String pcmFilePath = pcmFile.getAbsolutePath();
			return locator.createInvoker().addArg("-y").addArg("-f").addArg("s16le").addArg("-ar").addArg("24000")
					.addArg("-ac").addArg("1").addArg("-i").addArg(pcmFilePath).addArg(destFilePath);
		}
	}

	/**
	 * 将文件转换成PCM
	 *
	 * @return
	 */
	private File convertToPcm(String srcFilePath) {
		String cmd = "";
		String dir = "";
		if (SystemUtils.IS_OS_LINUX) {
			cmd = SILK_DECODER_LINUX;
			dir = SILK_DECODER_DIR_LINUX;
		} else {
			cmd = SILK_DECODER_WINDOWS;
			dir = SILK_DECODER_DIR_WINDOWS;
		}
		File silkDecoderDir = new File(dir);
		checkState(silkDecoderDir.exists(), "找不到SILK转换工具，请将转换工具上传到/usr/local/目录下并解压");
		String pcm = srcFilePath + ".pcm";
		CommandInvoker invoker = new CommandInvoker(cmd, dir);
		invoker.addArg(srcFilePath);
		invoker.addArg(pcm);
		try {
			invoker.invoke(30000);
			File pcmFile = new File(pcm);
			if (!pcmFile.exists()) {
				LOGGER.warn("转换文件失败，请确认silk格式是否正确！");
				return null;
			} else {
				return pcmFile;
			}
		} catch (IOException e) {
			LOGGER.warn("转换文件失败，请确认silk格式是否正确！", e);
		} catch (InterruptedException e) {
			LOGGER.warn("转换文件失败，请确认silk格式是否正确！", e);
		} catch (TimeoutException e) {
			LOGGER.warn("转换文件执行超时！", e);
		} finally {
			invoker.destroy();
		}
		return null;
	}

}
